<template>
  <a-popup
    :visible="mergeValue"
    placement="bottom"
    title="请选择"
    @cancel="handleCancel"
  >
    <view class="picks">
      <view class="picker-view">
        <picker-view
          :value="selectedIndex"
          :immediate-change="false"
          indicator-class="arco-picker-indicator"
          @pickstart="onPickStart"
          @pickend="onPickEnd"
          @change="handleTouchend"
        >
          <picker-view-column
            v-for="c in scrollColumns"
            :key="c.id"
            class="wd-picker-view-column"
          >
            <view
              v-for="(option, index) in c.column"
              :key="index"
              class="wraps"
            >
              <div class="text">{{ option[getOptionKey("text")] }}</div>
            </view>
          </picker-view-column>
        </picker-view>
      </view>
      <view>
        <a-button long type="primary">确定选择</a-button>
      </view>
    </view>
  </a-popup>
</template>

<script lang="ts">
import {
  computed,
  defineComponent,
  nextTick,
  PropType,
  reactive,
  ref,
  toRefs,
  watch,
} from "vue";
import aPopup from "../arco-popup/index.vue";
import useMergeState from "@/ArcoUni/hook/use-merge-state";
import { PickerColumnOption, ScrollColumn } from "./interface";

export default defineComponent({
  name: "Picker",
  components: {
    aPopup,
  },
  props: {
    modelValue: {
      type: Array as PropType<(string | number)[]>,
      default: () => [],
    },
    columns: {
      type: Array,
      default: () => [],
    },
    cascade: {
      type: Boolean,
      default: false,
    },
    childrenKey: {
      type: String,
      default: "children",
    },
    textKey: {
      type: String,
      default: "text",
    },
    valueKey: {
      type: String,
      default: "value",
    },
    columnsCount: [String, Number],
    /**
     * @zh 抽屉是否可见
     * @en Whether the drawer is visibles
     * @vModel
     */
    visible: {
      type: Boolean,
      default: false,
    },
    /**
     * @zh 抽屉默认是否可见（非受控模式）
     * @en Whether the drawer is visibles by default (uncontrolled mode)
     */
    defaultVisible: {
      type: Boolean,
      default: false,
    },
  },
  emits: ["update:visible", "update:modelValue"],
  setup(props, { emit }) {
    const { defaultVisible, visible, columns, cascade, modelValue } =
      toRefs(props);

    let sid = 0;

    const visibles = ref(props.defaultVisible);

    const value = ref([2]);

    const visibleColumnsCount = computed(() => props.columnsCount);

    const [mergeValue, setLocalValue] = useMergeState(
      defaultVisible.value,
      reactive({
        value: visible,
      }),
    );

    watch(
      () => props.visible,
      () => {
        const { indexes } = getPicked();
        setPrevIndexes(indexes);
      },
    );

    const scrollColumns = ref<ScrollColumn[]>([]);

    const selectedIndex = ref<Array<number>>([]); // 格式化之后，每列选中的下标集合

    function getPicked() {
      const values: (string | number)[] = [];
      const indexes: number[] = [];
      const options: PickerColumnOption[] = [];

      console.log(scrollColumns, "dada1");

      scrollColumns.value.forEach(({ column, index }) => {
        const option = column[index];
        values.push(getValue(option));
        indexes.push(index);
        options.push(option);
      });

      return {
        values,
        indexes,
        options,
      };
    }

    function getOptionKey(key: "text" | "value" | "children") {
      const keyMap = {
        text: props.textKey,
        value: props.valueKey,
        children: props.childrenKey,
      };

      return keyMap[key];
    }

    function getValue(option: PickerColumnOption): string | number {
      console.log(option, getOptionKey("value"), "我嘿嘿嘿");
      return option[getOptionKey("value")] ?? option[getOptionKey("text")];
    }

    function setPrevIndexes(indexes: number[]) {
      nextTick(() => {
        selectedIndex.value = [...indexes];
      });
    }

    function initScrollColumns() {
      scrollColumns.value = cascade.value
        ? normalizeCascadeMode(columns.value as PickerColumnOption[])
        : normalizeNormalMode(columns.value as PickerColumnOption[][]);
    }

    initScrollColumns();

    function normalizeCascadeMode(column: PickerColumnOption[]) {
      const scrollColumns: ScrollColumn[] = [];
      createChildren(scrollColumns, column);
      return scrollColumns;
    }

    function normalizeNormalMode(columns: PickerColumnOption[][]) {
      const visibleColumns =
        props.columnsCount != null
          ? columns.value.slice(0, visibleColumnsCount.value)
          : columns;
      return visibleColumns.map((column, idx) => {
        const scrollColumn: ScrollColumn = {
          id: sid++,
          prevY: 0,
          momentumPrevY: 0,
          touching: false,
          index: 0,
          duration: 0,
          momentumTime: 0,
          column,
          scrollEl: null,
          scrolling: false,
        };
        const value = modelValue.value[idx];
        const index = scrollColumn.column.findIndex(
          (option) => value === getValue(option),
        );
        scrollColumn.index = index === -1 ? 0 : index;
        // scrollTo(scrollColumn);
        return scrollColumn;
      });
    }

    function createChildren(
      scrollColumns: ScrollColumn[],
      children: PickerColumnOption[],
      syncModelValue = true,
      depth = 1,
    ) {
      if (
        children.length &&
        (props.columnsCount == null ||
          depth <= (visibleColumnsCount.value as number))
      ) {
        const scrollColumn: ScrollColumn = {
          id: sid++,
          prevY: 0,
          momentumPrevY: 0,
          touching: false,
          index: 0,
          duration: 0,
          momentumTime: 0,
          column: children,
          scrollEl: null,
          scrolling: false,
        };

        scrollColumns.push(scrollColumn);

        if (syncModelValue) {
          const value = modelValue.value[scrollColumns.length - 1];
          const index = children.findIndex(
            (option) => value === getValue(option),
          );
          scrollColumn.index = index === -1 ? 0 : index;
        }

        // scrollTo(scrollColumn);
        createChildren(
          scrollColumns,
          scrollColumn.column[scrollColumn.index][getOptionKey("children")] ??
            [],
          syncModelValue,
          depth + 1,
        );
      }
    }

    const index = ref(0);

    function handleTouchend({
      detail: { value },
    }: {
      detail: { value: number[] };
    }) {
      console.log(value, "我是你大爷");

      if (cascade.value) {
        // console.log(modelValue.value, scrollColumn.detail, "我真的无语了啊");
        console.log(modelValue.value, "我才是model");

        const { indexes } = getPicked();

        const index = value.findIndex((row, index) => {
          return row !== indexes[index];
        });

        // const index = modelValue.value.findIndex((row, index) => {
        //   return row !== value[index];
        // });
        scrollColumns.value[index].index = value[index];
        rebuildChildren(scrollColumns.value[index]);
      }

      // call(onChange, values, indexes, options)

      const { values, indexes } = getPicked();
      console.log(values, indexes, "我听不懂");

      emit("update:modelValue", values);
      // index.value = params.detail.value[0];
    }

    function rebuildChildren(scrollColumn: ScrollColumn) {
      // console.log(scrollColumns.value, scrollColumn, "我被删除了");
      if (scrollColumn) {
        scrollColumns.value.splice(
          scrollColumns.value.indexOf(scrollColumn) + 1,
        );
        createChildren(
          scrollColumns.value,
          scrollColumn.column[scrollColumn.index][getOptionKey("children")] ??
            [],
          false,
          scrollColumns.value.length + 1,
        );
        const { indexes } = getPicked();
        console.log(scrollColumns.value, "我是indexes");
        setPrevIndexes(indexes);
      }
    }

    function handleCancel() {
      visibles.value = false;
      emit("update:visible", false);
      setLocalValue(false);
    }

    function onPickStart() {
      console.log("我滚动开始了");
      // emit("pickstart");
    }

    function onPickEnd() {
      console.log("我滚动结束了了");
      // emit("pickend");
    }

    return {
      selectedIndex,
      scrollColumns,
      value,
      mergeValue,
      handleTouchend,
      visibles,
      index,
      handleCancel,
      onPickStart,
      onPickEnd,
      getOptionKey,
    };
  },
});
</script>

<style lang="scss">
.picks {
  padding-bottom: env(safe-area-inset-bottom);
}

.toolbar {
  display: flex;
  justify-content: space-between;
}

.picker-view {
  height: 300px;
}

.uni-picker-view-wrapper {
  height: 300px;
}

.wd-picker-view-column {
  height: 300px;
}

.uni-picker-view-content {
  height: 300px;
}

.arco-picker-indicator {
  background: #f5f5f5;
  z-index: 0;
  font: size 16P;
  color: rgba(0, 0, 0, 0.85);
  text-align: center;
}

.wraps {
  line-height: 34px;
  text-align: center;
}

.actice {
  // transform: scale(1.2);
  // transition: all 0.3 linear;
}
</style>
